package com.example.stock.business;

import com.example.stock.common.Constants;
import com.example.stock.excel.StockInfo;
import com.example.stock.excel.WeekLpUp;
import com.example.stock.model.GBSta;
import com.example.stock.model.WeekDetail;
import com.example.stock.service.*;
import com.example.stock.service.impl.GBStaServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;

@Component
public class StockListBusiness {

    @Autowired
    StockService stockService;

    @Autowired
    GBStaService gbStaService;

    @Autowired
    WeekDataService weekDataService;

    @Autowired
    StatisticService statisticService;

    @Autowired
    StockOperationService stockOperationService;

    @Autowired
    RankService rankService;

    public Map<String, Object> getStockList(String type) {

        Map<String, StockInfo> stockInfosMap = stockService.getStockInfosMap();

        Map<String, Object> ret = new HashMap<>();
        List<String> filter = new ArrayList<>();

        // 最近一周
        String lastedWeek = weekDataService.getWeekPctStatKeys().getFirst();

        switch (type) {
            case "20W_UP" -> filter = gbStaService.getGBStaUpByDate(lastedWeek, GBStaServiceImpl.GB_20W_K).stream()
                    .map(GBSta::getStock).toList();
            case "30W_UP" -> filter = gbStaService.getGBStaUpByDate(lastedWeek, GBStaServiceImpl.GB_30W_K).stream()
                    .map(GBSta::getStock).toList();
            case "60W_UP" -> filter = gbStaService.getGBStaUpByDate(lastedWeek, GBStaServiceImpl.GB_60W_K).stream()
                    .map(GBSta::getStock).toList();
            case "LP_UP" -> filter = statisticService.getWeekLpUp().get(lastedWeek).stream().map(WeekLpUp::getStock).toList();
            case "LP_LOW" -> filter = weekDataService.getWeekRawDataByDate(lastedWeek).stream()
                    .sorted(Comparator.comparing(WeekDetail::getLp))
                    .filter(item -> item.getLp() < 5)
                    .map(WeekDetail::getStock)
                    .toList();
            case "LP_TOP" -> filter = weekDataService.getWeekRawDataByDate(lastedWeek).stream()
                    .sorted(Comparator.comparing(WeekDetail::getLp).reversed())
                    .map(WeekDetail::getStock)
                    .limit(40)
                    .toList();
            case "DIS_PCT_LOW" -> filter = weekDataService.getWeekRawDataByDate(lastedWeek).stream()
                    .sorted(Comparator.comparing(WeekDetail::getDisPct))
                    .map(WeekDetail::getStock)
                    .limit(20)
                    .toList();
            case "DIS_PCT_TOP" -> filter = weekDataService.getWeekRawDataByDate(lastedWeek).stream()
                    .sorted(Comparator.comparing(WeekDetail::getDisPct).reversed())
                    .map(WeekDetail::getStock)
                    .limit(20)
                    .toList();
            // 在 60 周线附近的
            case "DIS_PCT_MID" -> filter = weekDataService.getWeekRawDataByDate(lastedWeek).stream()
                    .filter(i -> (i.getDisPct() < 3) && (i.getDisPct() > 0))
                    .map(WeekDetail::getStock)
                    .toList();
            case "MEAN_LT" -> filter = weekDataService.getWeekRawDataByDate(lastedWeek).stream()
                    .filter(i -> (i.getClose() <= i.getMean75Close())
                            && (i.getMean75Close() <= i.getMean20WClose())
                            && (i.getMean20WClose() <= i.getMean30WClose())
                            && (i.getMean30WClose() <= i.getMean300Close()))
                    .map(WeekDetail::getStock)
                    .toList();
            case "MEAN_GT" -> filter = weekDataService.getWeekRawDataByDate(lastedWeek).stream()
                    .filter(i -> (i.getClose() >= i.getMean75Close())
                            && (i.getMean75Close() >= i.getMean20WClose())
                            && (i.getMean20WClose() >= i.getMean30WClose())
                            && (i.getMean30WClose() >= i.getMean300Close()))
                    .map(WeekDetail::getStock)
                    .toList();
            case "60W_TOP" -> filter  = gbStaService.getDurGtList(GBStaServiceImpl.GB_60W_K, 60)
                            .stream().map(GBSta::getStock).distinct()
                            .limit(350).toList();
            case "RANK" -> filter = rankService.getStocksByRank();
            case "BASE" -> filter = Constants.getBaseStocks();
            // 近期操作
            case "LAST_OP" -> filter = stockOperationService.getLastedOperationStocks(600);
            case "STOCK_HOLD" -> filter = stockOperationService.getStockHold();
        }

        List<StockInfo> list;
        if (!filter.isEmpty()) {
            list = new ArrayList<>();
            filter.forEach( stock -> {
                list.add(stockInfosMap.get(stock));
            });
            ret.put("data", list);
        } else {
            list = new ArrayList<>(stockInfosMap.values()).stream().toList();
            ret.put("data", list);
        }

        ret.put("options", Arrays.asList(
                "ALL",
                "20W_UP", "30W_UP","60W_UP",
                "LP_UP","LP_LOW","LP_TOP",
                "MEAN_LT","MEAN_GT",
                "DIS_PCT_LOW","DIS_PCT_TOP", "DIS_PCT_MID",
                "60W_TOP",
                "RANK","BASE",
                "LAST_OP","STOCK_HOLD"));

        return ret;
    }
}
